package cn.zhm;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.FrameRecorder;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 启动主类
 */
public class Start extends Application {
    private static int frameRate = 30;// 录制的帧率
    private static boolean isStop = false;


    public static int height = 1080;

    public static int width = 1920;
    /**
     * 偏移
     */
    public static int x = 0;
    public static int y = 0;

    private static String path = "D://1.avi";

    @Override
    public void start(Stage primaryStage)  {
        primaryStage.setTitle("桌面录屏emm");
        Button button = new Button("停止录制");
        button.setOnAction(event -> {

                isStop = true;
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setTitle("info");
                alert.setHeaderText("已经停止录制");
                alert.setOnCloseRequest(event1 -> alert.hide());
                alert.showAndWait();
                System.exit(0);

        });


        Button c = new Button("选取区域");
        c.setOnAction((aa) -> {
            try {
                ScreenRecording.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        TextField field = new TextField(); // 创建一个单行输入框
        field.setPrefSize(50, 20); // 设置单行输入框的推荐宽高
        field.setEditable(true); // 设置单行输入框能否编辑
        field.setPromptText("帧数(10 - 60)"); // 设置单行输入框的提示语
        TextField field1 = new TextField(); // 创建一个单行输入框
        field1.setPrefSize(50, 20); // 设置单行输入框的推荐宽高
        field1.setEditable(true); // 设置单行输入框能否编辑
        field1.setPromptText("存储路径"); // 设置单行输入框的提示语

        Button s = new Button("开始录制");
        s.setOnAction((aa) -> {
            try {
                try {
                    if (!field1.getText().isEmpty())
                        path = field1.getText() + "1.MP4";
                    if (!field1.getText().isEmpty())
                        frameRate = Integer.parseInt(field.getText());
                }catch (Exception e){
                    e.printStackTrace();
                }

                s();
                field.setPromptText(frameRate +"");
                field1.setPromptText(path);
                field1.setEditable(false);
                field.setEditable(false);
                primaryStage.setTitle("已经开始");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        VBox box = new VBox();
        box.getChildren().addAll(button,s,c,field,field1);
        primaryStage.setScene(new Scene(box));
        primaryStage.setHeight(450);
        primaryStage.setWidth(450);
        primaryStage.show();
        primaryStage.setOnCloseRequest(event ->
                isStop = true
        );

    }

    private void s() throws Exception{
        // window 建议使用 FFmpegFrameGrabber("desktop") 进行屏幕捕捉
        FrameGrabber grabber = new FFmpegFrameGrabber("desktop");
        grabber.setFormat("gdigrab");
        grabber.setFrameRate(frameRate);
        grabber.setImageHeight(height);
        grabber.setImageWidth(width);
        grabber.setOption("offset_x", x + "");//必须设置了大小才能指定区域起点，参数可参考 FFmpeg 入参
        grabber.setOption("offset_y", y + "");

        // 用于存储视频 , 先调用stop，在释放，就会在指定位置输出文件，，这里我保存到D盘
        FrameRecorder recorder = FrameRecorder.createDefault(path, grabber.getImageWidth(), grabber.getImageHeight());
        recorder.setFrameRate(frameRate);
       // recorder.setFormat("mp4");
        /**
         * 码率
         */
        recorder.setVideoBitrate(height * width * (frameRate/15 + 1) );
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);// 编码，使用编码能让视频占用内存更小，根据实际自行选择
        // mp4
        //recorder.setAudioBitrate(avcodec.AV_CODEC_ID_MPEG4);
        grabber.start();
        recorder.start();
        System.out.println("********************* 已经开始 ***************");
        System.out.println(String.format("分辨率: %d * %d \n 文件存储位置: %s \n 帧数: %d",width,height,path,frameRate));

        Timer timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isStop) {
                    try {
                        // 停止
                        recorder.stop();
                        grabber.stop();

                        // 释放
                        recorder.release();
                        grabber.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    timer.cancel();
                    return;
                }
                try {
                    // 获取屏幕捕捉的一帧
                    Frame frame = grabber.grabFrame();

                    // 将这帧放到录制
                    recorder.record(frame);


                } catch (Exception e) {
                     e.printStackTrace();
                }
            }
        }, 100, 999 / frameRate);
    }

    public static void main(String[] args) throws Exception{
        launch();
    }
}
